package com.controller;

import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

@Controller
public class FileController {

    //真实开发中要么相对路径，要么配置文件进行配置路径，配置文件可以热插拔，默认路径为相对
    private static final String uploadPath = "E:/uploadFile";
    private static final String downloadPath = "E:/downloadFile";

    @GetMapping("/toupload") //向文件上传页面跳转
    public String toUpload() {return "upload";}

    @PostMapping("/uploadFile") //文件上传
    public String uploadFile(MultipartFile[] fileUpload, Model model)  {
        model.addAttribute("uploadStatus", "上传成功！"); //设置上传成功返回信息
        for (MultipartFile file : fileUpload) {
            String fileName = file.getOriginalFilename(); //获取文件名和后缀名
//            fileName = UUID.randomUUID() + "_" + fileName; //自定义文件名
            File filePath = new File(uploadPath);
            if (!filePath.exists()) filePath.mkdirs(); //创建路径
            try {
                file.transferTo(new File(uploadPath + File.separator + fileName)); //事务写入文件
            } catch (IOException e) {
                e.printStackTrace();
                model.addAttribute("uploadStatus", "上传失败：" + e.getMessage());
            }
        }
        return "upload"; //携带上传状态信息回调到文件上传页面
    }

    @GetMapping("/todownload") //向文件下载页面跳转
    public String toDownload() {return "download";}

    @GetMapping("/download") //所有类型文件下载管理
    public ResponseEntity<byte[]> fileDownload(HttpServletRequest request, String filename) throws IOException {
        File filePath = new File(downloadPath);
        if (!filePath.exists()) { //创建路径, 不存在，无法下载，也没有对应文件
            filePath.mkdirs();
            return new ResponseEntity<byte[]>("没有可用路径下载".getBytes("UTF-8"), HttpStatus.EXPECTATION_FAILED);
        }
        File file = new File(downloadPath + File.separator + filename); //创建目标存储路径对象
        HttpHeaders httpHeaders = new HttpHeaders(); //设置响应头
        //通知浏览器以下载方式打开（下载前对文件名进行转码）
        filename = getFilename(request, filename);
        httpHeaders.setContentDispositionFormData("attachment", filename);
        //这一步非常重要（必须设置响应流）
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); //定义以流的方式下载返回文件数据
        try {
            return new ResponseEntity<>(FileUtils.readFileToByteArray(file), httpHeaders, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<byte[]>(e.getMessage().getBytes(), HttpStatus.EXPECTATION_FAILED);
        }
    }

    //根据浏览器的不同进行编码设置，返回编码后的文件名
    private String getFilename(HttpServletRequest request, String filename) throws UnsupportedEncodingException {
        String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"}; //IE不同版本User-Agent中的值
        String userAgent = request.getHeader("User-Agent"); //获取请求头UA
        for (String keyWord : IEBrowserKeyWords) {
            if (userAgent.equals(keyWord)) {
                return URLEncoder.encode(filename, "UTF-8").replace("+", " ");
            }
        }
        return new String(filename.getBytes("UTF-8"), "ISO-8859-1");
    }

}
